import {
  Injectable,
  Logger,
  OnModuleDestroy,
  OnModuleInit,
} from '@nestjs/common';
import { Instance, NacosNamingClient } from 'nacos';
import { NacosConfigService } from '@app/nacos-config';

@Injectable()
export class NacosRegisterService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(NacosRegisterService.name);
  private client: NacosNamingClient;
  private instance: Instance;
  constructor(private readonly nacosConfigService: NacosConfigService) {
    // 自定义 logger 对象，符合 Console 接口
    const customLogger: Console = {
      // log: (msg: any) => this.logger.log(msg),
      info: (msg: any) => this.logger.log(msg),
      error: (msg: any) => this.logger.error(msg),
      warn: (msg: any) => this.logger.warn(msg),
      // debug: (msg: any) => this.logger.debug?.(msg),
      assert: console.assert, // 使用 console 的默认实现
      clear: console.clear,
      count: console.count,
      countReset: console.countReset,
      group: console.group,
      groupCollapsed: console.groupCollapsed,
      groupEnd: console.groupEnd,
      table: console.table,
      time: console.time,
      timeEnd: console.timeEnd,
      timeLog: console.timeLog,
      trace: console.trace,
      dir: console.dir,
      dirxml: console.dirxml,
      profile: console.profile,
      profileEnd: console.profileEnd,
      timeStamp: console.timeStamp,
      Console: undefined,
      debug: function (): void {
        // throw new Error('Function not implemented.');
      },
      log: function (): void {
        // throw new Error('Function not implemented.');
      },
    };

    this.client = new NacosNamingClient({
      logger: customLogger,
      serverList: ['127.0.0.1:8848'], // Nacos服务器地址
      namespace: 'public', // 使用的命名空间
    });
  }
  /**
   * 启动生命周期钩子
   */
  async onModuleInit() {
    await this.client.ready();
  }
  /**
   * 关闭生命周期钩子
   */
  async onModuleDestroy() {
    if (this.instance) {
      await this.romoveService(this.instance.serviceName);
    }
  }

  /**
   * 注册服务
   * @param serviceName 服务名称
   * @param serviceId 服务实例id
   * @param ip ip地址
   * @param port 端口号
   */
  async registerService(serviceName: string) {
    try {
      const res = await this.matchingService(serviceName);
      this.instance = {
        ip: res.ip,
        port: Number(res.port),
        instanceId: res.serviceId,
        enabled: true,
        healthy: true,
      };
      await this.client.registerInstance(serviceName, this.instance);
      this.logger.log(`Service ${serviceName} Nacos 注册成功`);
    } catch (error) {
      this.logger.error('Nacos 服务注册失败', error);
    }
  }

  /**
   * 注销服务
   * @param serviceName 服务名称
   * @param serviceId 服务实例id
   * @param ip ip地址
   * @param port 端口号
   */
  async romoveService(serviceName: string) {
    try {
      const res = await this.matchingService(serviceName);
      this.instance = {
        ip: res.ip,
        port: Number(res.port),
        instanceId: res.serviceId,
        enabled: true,
        healthy: true,
      };
      await this.client.deregisterInstance(serviceName, this.instance);
      this.logger.log(`Service ${serviceName} Nacos 注销成功`);
    } catch (error) {
      this.logger.error('Nacos 服务注销失败', error);
    }
  }

  /**
   * 查询 多个服务是否存在
   * @returns 数组包含 status 服务状态 true 在线 false 离线/不存在 name 服务名称 ip IP地址 port 端口号
   */
  async getAllService() {
    try {
      const serverList = await this.matchingServiceArrary();
      const result = [];
      for (const service of serverList) {
        const res = await this.client.getAllInstances(service.name);
        if (res.length === 0) {
          const list = {
            status: false,
            name: service.name,
            ip: service.ip,
            port: service.port,
          };
          result.push(list);
        } else {
          const list = {
            status: true,
            name: service.name,
            ip: service.ip,
            port: service.port,
          };
          result.push(list);
        }
      }
      return result;
    } catch (error) {
      this.logger.error(`服务查询故障 错误信息：${error}`);
    }
  }

  /**
   * 查询服务信息
   * 工具函数
   * @param serviceName 服务名
   * @returns 服务信息
   */
  async matchingService(serviceName: string) {
    try {
      const config = await this.nacosConfigService.getConfig(
        'dev-config',
        'DEFAULT_GROUP',
      );
      const res = { serviceId: '', ip: '', port: '' };
      if (serviceName === 'gateway-service') {
        res.serviceId = JSON.parse(config).GATEWAY_SERVICE_ID;
        res.ip = JSON.parse(config).GATEWAY_IP;
        res.port = JSON.parse(config).GATEWAY_TCP_PORT;
      } else if (serviceName === 'common-service') {
        res.serviceId = JSON.parse(config).COMMON_SERVICE_ID;
        res.ip = JSON.parse(config).COMMON_IP;
        res.port = JSON.parse(config).COMMON_TCP_PORT;
      } else if (serviceName === 'user-service') {
        res.serviceId = JSON.parse(config).USER_SERVICE_ID;
        res.ip = JSON.parse(config).USER_IP;
        res.port = JSON.parse(config).USER_TCP_PORT;
      } else if (serviceName === 'news-service') {
        res.serviceId = JSON.parse(config).NEWS_SERVICE_ID;
        res.ip = JSON.parse(config).NEWS_IP;
        res.port = JSON.parse(config).NEWS_TCP_PORT;
      }
      return res;
    } catch (error) {
      this.logger.error(`配置信息查询失败 错误信息：${error}`);
    }
  }
  async matchingServiceArrary() {
    try {
      const config = await this.nacosConfigService.getConfig(
        'dev-config',
        'DEFAULT_GROUP',
      );
      const serverList = [];
      JSON.parse(config).SERVICE_LIST.forEach((i: any) => {
        if (i === 'gateway-service') {
          const datas = {
            name: i,
            ip: JSON.parse(config).GATEWAY_IP,
            port: JSON.parse(config).GATEWAY_TCP_PORT,
          };
          serverList.push(datas);
        } else if (i === 'user-service') {
          const datas = {
            name: i,
            ip: JSON.parse(config).USER_IP,
            port: JSON.parse(config).USER_TCP_PORT,
          };
          serverList.push(datas);
        } else if (i === 'news-service') {
          const datas = {
            name: i,
            ip: JSON.parse(config).NEWS_IP,
            port: JSON.parse(config).NEWS_TCP_PORT,
          };
          serverList.push(datas);
        } else {
          const datas = {
            name: i,
            ip: null,
            port: null,
          };
          serverList.push(datas);
        }
      });
      return serverList;
    } catch (error) {
      this.logger.error(`配置信息查询失败 错误信息：${error}`);
    }
  }
}
